package controller;

import java.awt.Event;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.regex.PatternSyntaxException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Element;
import javax.swing.text.Highlighter;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import operations.AutoComplete;
import operations.BaseClass;
import operations.ClearAdditive;
import operations.CopyCutAdditiveOperations;
import operations.CopyCutOperations;
import operations.DiffFile;
import operations.FileOperations;
import operations.FindAllStrtagy;
import operations.FindNextStragtegy;
import operations.FindReplaceContext;
import operations.MacroOperations;
import operations.Paste;
import operations.ReplaceAllStrategy;
import operations.ReplaceNextStrategy;
import operations.SpellAction;
import userInterface.GraphicComponents;

/**
 * The Class EditorController.
 * This is the central class of the entire application. 
 * This class starts up the the GUI, sets action listeners.
 * This class also links the action listeners to the action doers in the other packages.
 */

public class EditorController extends GraphicComponents implements ActionListener, ClipboardOwner, DocumentListener {


	public static boolean flag;
	protected String command="", fileName="",completeName="",compareName="",fileDirectory="",textAreaContent="",Storedmacro="",SearchedWord="",ReplacedWord="";
	protected int count=0;
	protected SpellAction spellaction=new SpellAction();
	protected FileOperations fileOps = new FileOperations();
	protected CopyCutOperations copyCut = new CopyCutOperations();
	protected Paste pasteOps = new Paste();
	protected DiffFile diffFile=new DiffFile();
	protected ClearAdditive clearAdditive = new ClearAdditive();
	protected AutoComplete autoComp = new AutoComplete();
	protected CopyCutAdditiveOperations copyCutAdditive = new CopyCutAdditiveOperations();
	protected MacroOperations macroRecording= new MacroOperations(); 
	protected BaseClass BaseOperation =new BaseClass();
	protected FindReplaceContext FindReplaceContext;
	private static enum Mode { INSERT, COMPLETION };
	public static boolean unSavedFile;
	protected boolean copyCutAdditiveFlag;
	private static final String COMMIT_ACTION = "commit";
	public Mode mode = Mode.INSERT;
	private static final String TAB = "next";
	Highlighter h;


	/**
	 * Instantiates a new editor controller.
	 * This is the driving function of the entire application. When this function is called the
	 * graphicCompnents class constructor is also called. The editorController constructor sets
	 * action listeners to all the GUI components, sets key stroke actions, defines and controls 
	 * all the objects defined in the graphicComponents class.
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws NullPointerException the null pointer exception
	 */
	public EditorController() throws IOException,NullPointerException{
		setActionListeners();//sets action listeners for the GUI objects
		setKeyStrokeActions();//sets key stroke actions for the GUI objects
		addActionMap();//sets all the key stroke functions for the moving around the text editor
		

		text.getDocument().addDocumentListener(this);
		InputMap im = text.getInputMap();
	    ActionMap am = text.getActionMap();
	    im.put(KeyStroke.getKeyStroke("ENTER"), COMMIT_ACTION);
	    am.put(COMMIT_ACTION, new CommitAction());
	    im.put(KeyStroke.getKeyStroke("TAB"),TAB);
	    am.put(TAB, new CommitTab());
	    h= text.getHighlighter();
	    h.removeAllHighlights();
	    
		text.addMouseListener(new MouseListener() {
				
			public void mousePressed(MouseEvent e) {
				macroRecording.mousePressed(e); 
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub	
			}
			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		text.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent evt) {
            	macroRecording.updatecaret(text, macrotextarea);
            	facade.Client.TheString=text.getText();
        		JTextArea A= new JTextArea();
        		A=text;
        		facade.Client.Updateflag=true;
        		synchronized (A) {		
        			if(flag)facade.Server.carryon(A);	
				}	
            	}
        });
        text.addKeyListener(new KeyAdapter() {
        	
            public void keyTyped(KeyEvent evt) { 
            	EditorController.unSavedFile=true;	
            	Storedmacro=macroRecording.TextKeyTyped(text,macrotextarea,evt);
         
            }
            public void keyPressed(KeyEvent evt) {
                macroRecording.TextKeyPressed(text,macrotextarea,evt);
            }
        });
        addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
			if(unSavedFile==false) {
				System.exit(0);
			}
			int choice=unsaveddialog();
			if (choice!=2){
				System.exit(0);
			}
		}});
      
}
	
	
	/**
	 * Adds the action map.
	 * Invokes the map that matches the key stroke events to appropriate actions.
	 * 
	 */ 
	private void addActionMap()	{
		KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_N, Event.CTRL_MASK);
	    map.put(key, DefaultEditorKit.nextWordAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_M, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.previousWordAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.downAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.upAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_B, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.beginAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_E, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.endAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_L, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.beginLineAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_K, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.endLineAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.selectAllAction);
		key = KeyStroke.getKeyStroke(KeyEvent.VK_A, Event.CTRL_MASK);
		map.put(key, DefaultEditorKit.selectAllAction);
	}
	
	private void setSearchActionListeners()throws IOException,NullPointerException{
		FindAll.addActionListener(this);
		FindNext.addActionListener(this);
		SearchCancel1.addActionListener(this);
		WordCount1.addActionListener(this);
		SearchCancel2.addActionListener(this);
		WordCount2.addActionListener(this);
		ReplaceAll.addActionListener(this);
		ReplaceNext.addActionListener(this);
	}
	private void setSpellActionListeners()throws IOException,NullPointerException{
		CheckWord.addActionListener(this);
		AddToTextArea.addActionListener(this);
		AddToDictionry.addActionListener(this);
		ExitSpell.addActionListener(this);
	}
	/**
	 * Sets the action listeners.
	 *Sets the the action listeners for the menu items in the menu bar.
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws NullPointerException the null pointer exception
	 */
	private void setActionListeners() throws IOException,NullPointerException	{
		Newfile.addActionListener(this);
		Openfile.addActionListener(this);
		Sava_As.addActionListener(this);
		Save.addActionListener(this);
		Exit.addActionListener(this);
		Copy.addActionListener(this);
		Cut.addActionListener(this);
		Paste.addActionListener(this);
		Delete.addActionListener(this);
		Clear.addActionListener(this);
		Undo.addActionListener(this);
		Redo.addActionListener(this);
		Copyaddit.addActionListener(this);
		Cutaddit.addActionListener(this);
		Clearaddit.addActionListener(this);
		PlayRecording.addActionListener(this);
		StartRecording.addActionListener(this);
		StopRecording.addActionListener(this);
		ClearRecording.addActionListener(this);
		Find.addActionListener(this);
		Replace.addActionListener(this);
		SpellChecker.addActionListener(this);
	}
	
	/**
	 * Sets the key stroke actions.
	 * Sets key stroke shortcuts for the menu items in the application
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws NullPointerException the null pointer exception
	 */
	private void setKeyStrokeActions() throws IOException,NullPointerException	{
		Copy.setAccelerator(KeyStroke.getKeyStroke('Q',Event.CTRL_MASK));
		Cut.setAccelerator(KeyStroke.getKeyStroke('U',Event.CTRL_MASK));
		Delete.setAccelerator(KeyStroke.getKeyStroke('D',Event.CTRL_MASK));
		Clear.setAccelerator(KeyStroke.getKeyStroke('C',Event.CTRL_MASK));
		Undo.setAccelerator(KeyStroke.getKeyStroke('T',Event.CTRL_MASK));
		Redo.setAccelerator(KeyStroke.getKeyStroke('Y',Event.CTRL_MASK));
		Paste.setAccelerator(KeyStroke.getKeyStroke('P',Event.CTRL_MASK));
		Sava_As.setAccelerator(KeyStroke.getKeyStroke('S',Event.SHIFT_MASK));
		Save.setAccelerator(KeyStroke.getKeyStroke('J',Event.CTRL_MASK));
		Openfile.setAccelerator(KeyStroke.getKeyStroke('O',Event.CTRL_MASK));
		Newfile.setAccelerator(KeyStroke.getKeyStroke('G',Event.CTRL_MASK));
		Exit.setAccelerator(KeyStroke.getKeyStroke('H',Event.SHIFT_MASK));
		Copyaddit.setAccelerator(KeyStroke.getKeyStroke('C',Event.SHIFT_MASK));
		Cutaddit.setAccelerator(KeyStroke.getKeyStroke('X',Event.SHIFT_MASK));
		Clearaddit.setAccelerator(KeyStroke.getKeyStroke('B',Event.SHIFT_MASK));
		StartRecording.setAccelerator(KeyStroke.getKeyStroke('Z',Event.CTRL_MASK));
		StopRecording.setAccelerator(KeyStroke.getKeyStroke('X',Event.CTRL_MASK));
		PlayRecording.setAccelerator(KeyStroke.getKeyStroke('F',Event.CTRL_MASK));
		ClearRecording.setAccelerator(KeyStroke.getKeyStroke('V',Event.CTRL_MASK));
		Find.setAccelerator(KeyStroke.getKeyStroke('F',Event.SHIFT_MASK));
		Replace.setAccelerator(KeyStroke.getKeyStroke('R',Event.SHIFT_MASK));
		SpellChecker.setAccelerator(KeyStroke.getKeyStroke('S',Event.SHIFT_MASK));
	}
	
	/**
	 * Sets the file dialog to visible.
	 * Sets the file dialog to visible when open or save as menu items are clicked
	 * @param fileDialog the new file dialog to visible
	 */
	public void setFileDialogToVisible(String fileDialog)	{//controls the visibility of the file dialog objects in the graphicComponents class
		if (fileDialog=="open")
			dialogOpen.setVisible(true);
		else if (fileDialog=="saveas")
			dialogSaveAs.setVisible(true);
		else if (fileDialog=="Compareto")
			dailogCompareTo.setVisible(true);
	}
	
	/**
	 * File dialog get diretory.
	 * This function gets the file directory information from the file dialog box
	 * @param fileDialogName the file dialog name
	 * @return the string
	 */
	public String fileDialogGetDiretory(String fileDialogName)	{
		if (fileDialogName=="open")
			return dialogOpen.getDirectory() ;
		else if (fileDialogName=="saveas")
			return dialogSaveAs.getDirectory() ;
		else if (fileDialogName=="Compareto")
			return dailogCompareTo.getDirectory() ;
		else
			return "an exception hass occured!!";
	}
	
	/**
	 * File dialog get file.
	 * This function get the file name entered by the user
	 * @param fileDialogName the file dialog name
	 * @return the string
	 */
	public String fileDialogGetFile(String fileDialogName)	{
		if (fileDialogName=="open")
			return dialogOpen.getFile() ;
		else if (fileDialogName=="saveas")
			return dialogSaveAs.getFile() ;
		else if (fileDialogName=="Compareto")
			return dailogCompareTo.getFile() ;
		else
			return "an exception hass occured!!";
	}
	
	/**
	 * Sets the text area.
	 * This function sets the text area in GUI with the argument textAreaData
	 * @param textAreaData the new text area
	 */
	public void setTextArea(String textAreaData)	{
		text.setText(textAreaData);
	}
	
	/**
	 * Gets the text area.
	 * This function returns the text in the text area of the GUI
	 * @return the text area
	 */
	public String getTextArea()	{
		return text.getText();
	}
	
	
	public void actionPerformed(ActionEvent action)	{
		command=(String)action.getActionCommand();//action listener's result is stored in the command string
	        
		if(command.equalsIgnoreCase("New File")){
			Thread t = new Thread ( new Runnable ( ){
				public void run () {
					System.out.println("111   "+getTextArea());
					fileOps.Newfile();
					}
				});
				t.start() ;
				System.out.println("2222   "+getTextArea());
		
	}
	else if(command.equalsIgnoreCase("Open File")){
		Thread t = new Thread ( new Runnable ( ){
			public void run () {
			try {
				setFileDialogToVisible("open");
				fileDirectory=fileDialogGetDiretory("open");
				fileName=fileDialogGetFile("open");
				completeName=fileDirectory+fileName;
				text.setText(fileOps.Openfile(completeName));	
			}
			catch (IOException e) {}
			}
		});
		t.start() ;
	}
	else if(command.equalsIgnoreCase("Save"))	{
		try{
			textAreaContent = getTextArea();
			if ((fileName!="")&&(fileDirectory!=null))	{
				fileOps.Save(textAreaContent,completeName);
			}
			else{
				textAreaContent = getTextArea();
				setFileDialogToVisible("saveas");
				fileDirectory=fileDialogGetDiretory("saveas");
				fileName=fileDialogGetFile("saveas");
				if(fileDirectory!=null){
					if(fileName.contains(".")){
						completeName=fileDirectory+fileName;
					}
					else{
						completeName=fileDirectory+fileName+".txt";
					}
					fileOps.saveAs(textAreaContent,completeName);
					this.setTitle(fileName);
				}
			}
		}
		catch (IOException e){}
	}
	else if(command.equalsIgnoreCase("Save As"))	{
		
		try{if ((fileName!="")&&(fileDirectory!=null))	{
			fileOps.Save(textAreaContent,completeName);
		}
			textAreaContent = getTextArea();
			setFileDialogToVisible("saveas");
			fileDirectory=fileDialogGetDiretory("saveas");
			fileName=fileDialogGetFile("saveas");
			if(fileDirectory!=null){
				if(fileName.contains(".")){
					completeName=fileDirectory+fileName;
				}
				else {
					completeName=fileDirectory+fileName+".txt";
				}
				fileOps.saveAs(textAreaContent,completeName);
				this.setTitle(fileName);
			}
		}
		catch (IOException e){}
	}
	else if (command.equalsIgnoreCase("Clear")) {
		text.setText("");

	}
	else if(command.equalsIgnoreCase("Compare As")){
		text.setText("");
		if ((fileName!="")&&(fileDirectory!=null)){}
		else{
			textAreaContent = getTextArea();
			fileDirectory=".\\";
			fileName="temp";
			if(fileDirectory!=null){
				if(fileName.contains(".")){
					completeName=fileDirectory+fileName;
				}
				else{
					completeName=fileDirectory+fileName+".txt";
				}
				try {
					fileOps.Save(textAreaContent,completeName);
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
			
			}
			
		setFileDialogToVisible("Compareto");
		fileDirectory=fileDialogGetDiretory("Compareto");
		fileName=fileDialogGetFile("Compareto");
		if(fileDirectory!=null){
			if(fileName.contains(".")){
				compareName=fileDirectory+fileName;
			}
			else {
				compareName=fileDirectory+fileName+".txt";
			}
			diffFile.doDiff(compareName, completeName);
			
			Thread t = new Thread ( new Runnable ( ){
				public void run () {
					try {
						fileOps.Newfile();
						text.setText(fileOps.Openfile(compareName));
					} catch (IOException e) {
						e.printStackTrace();
					}
					}
				});
				t.start() ;
		}}
	
	else if(command.equalsIgnoreCase("Exit"))	{
		if(unSavedFile==false){
			this.setVisible(false);
		}
		int choice=unsaveddialog();
		if (choice!=2){
			this.setVisible(false);
		}
	}
		else if(command.equalsIgnoreCase("Copy"))	{
			try 	{
				if(text.getSelectedText().equals(null))	{		}
				else{
					copyCut.performOperation(text.getSelectedText());
					copyCutAdditiveFlag=false;}
			}
		catch (Exception NullPointerException)		{ 
			
		}

		}
		else if(command.equalsIgnoreCase("Cut"))	{
			copyCut.performOperation(text.getSelectedText());
			int startIndex=text.getSelectionStart();
			int endIndex=text.getSelectionEnd();
			text.replaceRange("",startIndex,endIndex);
			copyCutAdditiveFlag=false;
		}
		else if(command.equalsIgnoreCase("Delete"))	{
			try 	{
				if(text.getSelectedText().equals(""))	{		
					throw new NullPointerException(" The selected area shouldn't be empty");
				}
				else	{
					int startIndex=text.getSelectionStart();
					int endIndex=text.getSelectionEnd();
					text.replaceRange("",startIndex,endIndex);
				}
			}
			catch (Exception NullPointerException)		{ 
				System.err.println("You can't use the delete feature on an empty space");
			}
		}
		else if(command.equalsIgnoreCase("Paste"))	{
	            int index=text.getCaretPosition();
				text.insert(pasteOps.performOperation(),index);
		
		}
		else if(command.equalsIgnoreCase("Additive Copy"))	{
			copyCutAdditive.performOperation(text.getSelectedText());
			copyCutAdditiveFlag=true;
			
		}
		else if(command.equalsIgnoreCase("Additive Cut"))	{
				copyCutAdditiveFlag=true;
				copyCutAdditive.performOperation(text.getSelectedText());
				int startIndex=text.getSelectionStart();
				int endIndex=text.getSelectionEnd();
				text.replaceRange("",startIndex,endIndex);
			
		}
		else if (command.equalsIgnoreCase("Clear Additive"))	{
			if (copyCutAdditiveFlag){
				clearAdditive.performOperation();	
			}
		}

		else if (command.equalsIgnoreCase("Undo"))	{
			doUndo();
		}
		else if (command.equalsIgnoreCase("Redo"))	{
			doRedo();
		}
	
		else if (command.equalsIgnoreCase("Play Recording"))	{
			int index=text.getCaretPosition();
			macroRecording.PlayRecording(text,Storedmacro,index);
		}
		else if (command.equalsIgnoreCase("Start Recording"))	{
			KeyEvent KeyboardEvent = new KeyEvent(StartRecording, 400,ALLBITS, StartRecording.getAccelerator().getModifiers(),  0, (char)26);
	        macroRecording.TextKeyTyped(text,macrotextarea,KeyboardEvent);
		}
		else if (command.equalsIgnoreCase("Stop Recording"))	{
			KeyEvent KeyboardEvent = new KeyEvent(StartRecording, 400,ALLBITS, StartRecording.getAccelerator().getModifiers(), 0, (char)24);
			macroRecording.TextKeyTyped(text,macrotextarea,KeyboardEvent);
		}
		else if (command.equalsIgnoreCase("Clear Recording"))	{
			Storedmacro="";
		}
		else if (command.equalsIgnoreCase("Find"))	{
			createSearchWindow();
			Find.requestFocus();
			try {
				setSearchActionListeners();
			} catch (NullPointerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
			
		}
		else if(command.equalsIgnoreCase("Find All"))
		{
			try {
				SearchedWord=text1.getText();
				if(SearchedWord.equals("")){
					// Do nothing 
				}
				else{
					FindReplaceContext=new FindReplaceContext();
					FindReplaceContext.setFinder(new FindAllStrtagy());
					FindReplaceContext.FindPattern(text,SearchedWord);
				}
			} catch (PatternSyntaxException e) {

				e.printStackTrace();
			}
		}
		else if (command.equalsIgnoreCase("Find Next"))
		{
			try {
				SearchedWord=text1.getText();
				if(SearchedWord.equals("")){
					// Do nothing 
				}
				else{
					FindReplaceContext=new FindReplaceContext();
					FindReplaceContext.setFinder(new FindNextStragtegy());
					FindReplaceContext.FindPattern(text,SearchedWord);
				}
			} catch (PatternSyntaxException e) {

				e.printStackTrace();
			}
		}
		else if(command.equalsIgnoreCase("Replace All")){
			try{
			FindReplaceContext=new FindReplaceContext();	
			SearchedWord=text4.getText();
			ReplacedWord=text7.getText();
			FindReplaceContext.setReplacer(new ReplaceAllStrategy());
			FindReplaceContext.ReplacePattern(text,SearchedWord,ReplacedWord);
			}
			catch (PatternSyntaxException e) {
				
				e.printStackTrace();
			}
		}
		else if(command.equalsIgnoreCase("Replace Next")){
			try{
		    FindReplaceContext=new FindReplaceContext();
			SearchedWord=text4.getText();
			ReplacedWord=text7.getText();
			FindReplaceContext.setReplacer(new ReplaceNextStrategy());
			FindReplaceContext.ReplacePattern(text,SearchedWord,ReplacedWord);
			}
			catch (PatternSyntaxException e) {
				
				e.printStackTrace();
			}
		}
		else if(command.equalsIgnoreCase("Cancel..."))
		{
			BaseOperation.RemoveHighlights(text);
			frame.dispose();
		} 
        else if (command.equalsIgnoreCase("Word Count")){
        	SearchedWord=text4.getText();
        	if(SearchedWord.equals("")){
        		// Do Nothing
        	}
        	else{
			count=BaseOperation.CoundWord(text, SearchedWord);
			createCountWindow();
			Counttext.setText("   Found "+count+" match(es) to " +SearchedWord);
			}
		}
        else if (command.equalsIgnoreCase("Word Count ")){
        	SearchedWord=text1.getText();
        	if(SearchedWord.equals("")){
        		// Do Nothing
        	}
        	else{
			count=BaseOperation.CoundWord(text, SearchedWord);
			createCountWindow();
			Counttext.setText("   Found "+count+" match(es) to " +SearchedWord);
			}
		}
		
        else if (command.equalsIgnoreCase("Spell Checker")){
        	createSpellWindow();
        	Spellframe.requestFocus();
        	try {
				setSpellActionListeners();
			} catch (NullPointerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
        else if(command.equalsIgnoreCase("Click to Check Word")){
        	String textFieldContents = SpellText1.getText();
			String finalResult=spellaction.doAction(textFieldContents);
			SpelltextArea.setText(finalResult);
		}
		else if(command.equalsIgnoreCase("Exit Spell Check")){
			Spellframe.dispose();
		}
		else if(command.equalsIgnoreCase("Add To the TextArea")){
			String textAreaContents = SpelltextArea.getSelectedText();
			int index=text.getCaretPosition();
		    text.insert(textAreaContents,index);
		}
		else if(command.equalsIgnoreCase("Add To the Dictionry")){
		//    	Tree<String> tst = new Tree<String>();
		//		tst.save(SpellText1.getText(),SpellText1.getText());
		//		System.out.println("No way "+SpellText1.getText());
		}
      
		else if (command.equalsIgnoreCase("Replace")){
			
			createSearchWindow();
			tab.getComponentZOrder(Replace);
			try {
				setSearchActionListeners();
			} catch (NullPointerException e) {

				e.printStackTrace();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
			
		}
	}
	
	
	/**
	 * Do undo.
	 * This function is called when the action listener encounters this undo operation.
	 * 
	 * @return true, if successful
	 */
	public boolean doUndo() {
        try{
                manager.undo(); }
                catch(CannotUndoException e){
                        System.err.println("You can't undo in this case");
                        return false;
                }
        return true;
}

	/**
	 * Do redo.
	 * This function is called when the action listener encounters this redo operation.
	 * @return true, if successful
	 */
	public boolean doRedo()
	{
        try{
                manager.redo(); }
                catch(CannotRedoException e){
                        System.err.println("You can't redo in this case");
                        return false;
                }
                return true;
}
	
	/**
	 * Unsaveddialog.
	 * This function is called when the user tries quit an unsaved file for another task.
	 * @return the int
	 */
	public int unsaveddialog(){
		Object[] options = {"Save File","No, thanks","Cancel"};
		int choice = JOptionPane.showOptionDialog(this,"Would you like to save your current File","Exit",JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,null,options,options[2]);
		if(choice==0){
				textAreaContent = getTextArea();
				setFileDialogToVisible("saveas");
				fileDirectory=fileDialogGetDiretory("saveas");
				if(!(fileDirectory==null)){
					fileName=fileDialogGetFile("saveas");
					completeName=fileDirectory+fileName+".txt";
					try {
						fileOps.saveAs(textAreaContent,completeName);
					} catch (IOException e) {
						e.printStackTrace();
					}
				this.setTitle(fileName);
				}
				else{
					choice=2;
				}		
		}
		return choice;
	}
	public void lostOwnership(Clipboard clipboard, Transferable contents) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

	@Override
	public void changedUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		lines.setText(getText());
		
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		autoComp.insertUpdate(e,getTextArea());
		lines.setText(getText());
		
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		// TODO Auto-generated method stub
		lines.setText(getText());
		
	}
	public String getText(){
		int caretPosition = text.getDocument().getLength();
		Element root = text.getDocument().getDefaultRootElement();
		String text = "1" + System.getProperty("line.separator");
		for(int i = 2; i < root.getElementIndex( caretPosition ) + 2; i++){
			text += i + System.getProperty("line.separator");
		}
		return text;
	}
private class CompletionTask implements Runnable {
    String completion;
    int position;

    CompletionTask(String completion, int position) {
        this.completion = completion;
        this.position = position;
    }

    public void run() {
    	 text.insert(completion, position);
         text.setCaretPosition(position + completion.length());
         text.moveCaretPosition(position);
         mode = Mode.COMPLETION;
    }
}

	public class CommitTab extends AbstractAction {
		//For Completing the word on enter
		 public void actionPerformed(ActionEvent ev) {
			 autoComp.commitTab.actionPerformed(ev);
	            }
	}
	public class CommitAction extends AbstractAction {
		//For Completing the word on enter
		 public void actionPerformed(ActionEvent ev) {
			 autoComp.commitAction.actionPerformed(ev);
	            }
	}
}



